/* eslint-disable prefer-const */

export default function Tpl(tpl) {
  let
    fn
  let match
  const code = ['var r=[];\nvar _html = function (str) { return str.replace(/&/g, \'&amp;\').replace(/"/g, \'&quot;\').replace(/\'/g, \'&#39;\').replace(/</g, \'&lt;\').replace(/>/g, \'&gt;\'); };']
  const re = /\{\{\s*([a-zA-Z\.\_0-9()]+)(\s*\|\s*safe)?\s*\}\}/m
  const addLine = function (text) {
    code.push('r.push(\'' + text.replace(/\'/g, '\\\'').replace(/\n/g, '\\n').replace(/\r/g, '\\r') + '\');')
  }
  // eslint-disable-next-line no-cond-assign
  while (match = re.exec(tpl)) {
    if (match.index > 0) {
      addLine(tpl.slice(0, match.index))
    }
    if (match[2]) {
      code.push('r.push(String(this.' + match[1] + '));')
    } else {
      code.push('r.push(_html(String(this.' + match[1] + ')));')
    }
    tpl = tpl.substring(match.index + match[0].length)
  }
  addLine(tpl)
  code.push('return r.join(\'\');')
  // eslint-disable-next-line no-new-func
  fn = new Function(code.join('\n'))
  this.render = function (model) {
    return fn.apply(model)
  }
}

// 另外一种
// String.prototype.render = function (context) {
//   return this.replace(/\{\{(.*?)\}\}/g, (match, key) => context[key.trim()]);
// };
// 使用方式：str.render(data)

export function renderStr(str, obj) {
  return str.replace(/\{\{(.*?)\}\}/g, (match, key) => obj[key.trim()])
}
// 使用方式：renderStr(str, obj)
